/**
 * @version Mar 29 2012
 * @author Travis C lynch <travisclynch@student.midlandstech.edu>
 * 
 * <p>
 * <b>Instructions:</b><br>
 * <ul>
 * <li>contains a queue of Customer objects 
 * <li>has a constructor with 3 int parameters 
 * <ul>
 * <li>the number of seconds to run the simulation 
 * <li>the maximum time before a new customer comes, in seconds 
 * <li>the maximum time to handle one customer's transactions, in seconds 
 * </ul></li>
 * <li>has a public void run()method to run the simulation
 * <ul>
 * <li>Generate a random number less than the second constructor parameter for when the next customer arrives. 
 * <li>Loop while a clock variable is less than the number of seconds to run the simulation. 
 * <ul>
 * <li>If the time has elapsed for a new customer to arrive, enqueue a new customer and generate a random number for the next clock time when a customer will arrive. 
 * <li>If the teller is not busy, dequeue a customer, accumulate the number of customers served and the total wait time, and generate a random number to calculate the next clock time when the teller will be free. 
 * <li>increment the clock time 
 * </ul></ul>
 * <li>has a public void report()method to output, clearly labeled, 
 * <ul>
 * <li>the Total time in minutes. 
 * <li>the Average wait time in minutes. 
 * <li>the Number served 
 * <li>If the queue is not empty 
 * <ul>
 * <li>the number of customers still in line 
 * <li>the wait time of the customer in front of the line, in minutes. 
 * </ul></ul></ul>
 * <b>Description:</b><br>
 * A class that models the wait time for customers under waiting conditions
 * 
 */
public class Teller {
	/**
	 * clock = the clock that keeps cycle time for the program
	 * runTime = feild for the param a
	 * maxNextCustomer = feild for the param b
	 * maxHelptime = feild for param c
	 * customersHelped = Keeps track over the amount of customers helped
	 * helpTime = keeps track of the current help time for the poped customer in the que
	 * nextCustomerTime = keeps track of the time when te next customer will be pushed onto the que
	 * waitTime = keeps the total time each customer waited in line before teller helped them
	 */
	private int clock, runTime, maxNextCustomer, maxHelpTime, customersHelped, helpTime, nextCustomerTime, waitTime;
	private boolean ran = false;
	Queue<Customer> line;
	Customer helping = null;
	/**
	 * @param a The overall run time for the teller
	 * @param b The max time it takes for a new customer to cue up
	 * @param c The max time it takes to help each customer
	 */
	public Teller(int a, int b, int c ){
		runTime =a;
		maxNextCustomer = b;
		maxHelpTime = c;
		line = new Queue<Customer>();
		line.enqueue(new Customer(clock));
	}
	/**
	 * 
	 */
	public void run(){
		ran = true;
		line = new Queue<Customer>();
		clock=0;
		customersHelped=0;
		helpTime=0;
		nextCustomerTime=0; 
		waitTime=0;
		while(clock < runTime){
			if((line.length()>0) || (clock >= helpTime)){
				if(helping!=null) waitTime += helping.getWait(clock);
				helping = line.dequeue();
				helpTime = (clock + ((int)(maxHelpTime * Math.random())));
				customersHelped++;	
			}
			if(clock >= nextCustomerTime){
				line.enqueue(new Customer(clock));
				nextCustomerTime = (clock + ((int)(maxNextCustomer * Math.random())));
			}
			clock++;
		}
	}
	/**
	 * @return String returns a report of the overall performance of the teller
	 */
	public String report(){
		if (ran) return "This teller ran for "+runTime+" Cycles, helped "+customersHelped+" customers, and had "+line.length()+" more customers to help before thay quit. The adversage wait time for each customer was "+ (waitTime)+" Cycles.";
		return "please run this teller before running a report";
		
	}

}
